package com.fzq.config.security;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.method.configuration.EnableGlobalMethodSecurity;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.builders.WebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.config.http.SessionCreationPolicy;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter;


@Slf4j
@EnableGlobalMethodSecurity(prePostEnabled = true)
public class WebSecurityConfig extends WebSecurityConfigurerAdapter {

    @Autowired
    private LoginService loginService;
    @Autowired
    private SimpleAuthenticationFailureHandler simpleAuthenticationFailureHandler;
    @Autowired
    private SimpleAuthenticationSuccessHandler simpleAuthenticationSuccessHandler;
    @Autowired
    private SimpLogoutSuccessHandler logoutSuccessHandler;
    @Autowired
    private JwsTokenFilter jwsTokenFilter;
    @Autowired
    private SimpleAuthenticationEntryPoint simpleAuthenticationEntryPoint;
    @Autowired
    private SimpleAccessDeniedHandler simpleAccessDeniedHandler;



    @Bean
    public PasswordEncoder passwordEncoder(){
        return new BCryptPasswordEncoder();
    }

    @Override
    protected void configure(AuthenticationManagerBuilder auth) throws Exception {
        auth.userDetailsService(loginService).passwordEncoder(passwordEncoder());
    }

    /**
     * 放行swagger静态资源不拦截
     * @param web
     * @throws Exception
     */
    @Override
    public void configure(WebSecurity web) throws Exception {
        web.ignoring().antMatchers(HttpMethod.GET,"/html/**");
    }


    @Override
    protected void configure(HttpSecurity http) throws Exception {

        //鉴权相关过滤器
        http.authorizeRequests()
                .antMatchers("/","/minio/push","/minio/push/test").permitAll()
                .anyRequest()
                .authenticated();

        //认证相关过滤器
        http.formLogin()
                .loginPage("/html/login.html")  //配置自己的登录界面
                .loginProcessingUrl("/login") //配置登录的请求路径
//                .usernameParameter("username").passwordParameter("password")
                .successHandler(simpleAuthenticationSuccessHandler)
                .failureHandler(simpleAuthenticationFailureHandler)
                .permitAll(); //很重要 放开login.html 和 dologin 的访问权

        // 退出登录处理器
        http.logout().logoutSuccessHandler(logoutSuccessHandler);


        http.exceptionHandling()
                .authenticationEntryPoint(simpleAuthenticationEntryPoint)  //认证异常 失败时
                .accessDeniedHandler(simpleAccessDeniedHandler); //鉴权异常 失败时

        //把我们自定义恢复身份的过滤器加入过滤链中 放在UsernamePasswordAuthenticationFilter之后
        http.addFilterAfter(jwsTokenFilter, UsernamePasswordAuthenticationFilter.class);


        // 关闭CSRF攻击
        http.csrf().disable();
        //关闭session
        http.sessionManagement().sessionCreationPolicy(SessionCreationPolicy.STATELESS);
    }


}
